/**
 * 事件监听器模块 - 处理编辑器的各种事件监听逻辑
 */
import { debounce, nextTick, scrollIntoView } from '../../utils'
import { ControlState, ElementType, ListStyle, ListType } from '../../editor'

/**
 * 初始化事件监听器
 * @param instance 编辑器实例
 */
export default function initEventListeners(instance: any) {
  // 确保实例和必要的方法存在
  if (!instance || !instance.listener) {
    console.warn('编辑器实例或监听器不存在')
    return
  }

  // 初始化DOM元素引用
  const subscriptDom = document.querySelector<HTMLDivElement>('.menu-item__subscript') || null
  const superscriptDom = document.querySelector<HTMLDivElement>('.menu-item__superscript') || null
  const separatorDom = document.querySelector<HTMLDivElement>('.menu-item__separator') || null
  const separatorOptionDom = separatorDom ? separatorDom.querySelector<HTMLDivElement>('.options') : null
  const fontOptionDom = document.querySelector<HTMLDivElement>('.menu-item__font .options')!
  const fontSelectDom = document.querySelector<HTMLDivElement>('.menu-item__font .select')!
  const sizeOptionDom = document.querySelector<HTMLDivElement>('.menu-item__size .options')!
  const sizeSelectDom = document.querySelector<HTMLDivElement>('.menu-item__size .select')!
  const boldDom = document.querySelector<HTMLDivElement>('.menu-item__bold')!
  const italicDom = document.querySelector<HTMLDivElement>('.menu-item__italic')!
  const underlineDom = document.querySelector<HTMLDivElement>('.menu-item__underline')!
  const strikeoutDom = document.querySelector<HTMLDivElement>('.menu-item__strikeout')!
  const colorDom = document.querySelector<HTMLDivElement>('.menu-item__color')!
  const colorControlDom = document.querySelector<HTMLInputElement>('.menu-item__color input')!
  const colorSpanDom = document.querySelector<HTMLSpanElement>('.menu-item__color span')!
  const highlightDom = document.querySelector<HTMLDivElement>('.menu-item__highlight')!
  const highlightControlDom = document.querySelector<HTMLInputElement>('.menu-item__highlight input')!
  const highlightSpanDom = document.querySelector<HTMLSpanElement>('.menu-item__highlight span')!
  const leftDom = document.querySelector<HTMLDivElement>('.menu-item__left')!
  const centerDom = document.querySelector<HTMLDivElement>('.menu-item__center')!
  const rightDom = document.querySelector<HTMLDivElement>('.menu-item__right')!
  const alignmentDom = document.querySelector<HTMLDivElement>('.menu-item__alignment')!
  const justifyDom = document.querySelector<HTMLDivElement>('.menu-item__justify')!
  const rowOptionDom = document.querySelector<HTMLDivElement>('.menu-item__row .options')!
  const undoDom = document.querySelector<HTMLDivElement>('.menu-item__undo')!
  const redoDom = document.querySelector<HTMLDivElement>('.menu-item__redo')!
  const painterDom = document.querySelector<HTMLDivElement>('.menu-item__painter')!
  const titleOptionDom = document.querySelector<HTMLDivElement>('.menu-item__title .options')!
  const titleSelectDom = document.querySelector<HTMLDivElement>('.menu-item__title .select')!
  const listOptionDom = document.querySelector<HTMLDivElement>('.menu-item__list .options')!
  const listDom = document.querySelector<HTMLDivElement>('.menu-item__list')!

  const commentDom = document.querySelector<HTMLDivElement>('.comment')!

  const pageModeOptionsDom = document.querySelector<HTMLDivElement>('.page-mode .options')!
  const isCatalogShow = true

  // 内部事件监听 - 范围样式变化
  instance.listener.rangeStyleChange = function (payload: any) {
    // 控件类型
    if (subscriptDom) {
      payload.type === ElementType.SUBSCRIPT ? subscriptDom.classList.add('active') : subscriptDom.classList.remove('active')
    }
    if (superscriptDom) {
      payload.type === ElementType.SUPERSCRIPT ? superscriptDom.classList.add('active') : superscriptDom.classList.remove('active')
    }
    if (separatorDom) {
      payload.type === ElementType.SEPARATOR ? separatorDom.classList.add('active') : separatorDom.classList.remove('active')
    }
    if (separatorOptionDom) {
      separatorOptionDom.querySelectorAll('li').forEach(li => li.classList.remove('active'))
      if (payload.type === ElementType.SEPARATOR) {
        const separator = payload.dashArray.join(',') || '0,0'
        const curSeparatorDom = separatorOptionDom.querySelector<HTMLLIElement>(`[data-separator='${separator}']`)!
        if (curSeparatorDom) {
          curSeparatorDom.classList.add('active')
        }
      }
    }

    // 富文本
    fontOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
    const curFontDom = fontOptionDom.querySelector<HTMLLIElement>(`[data-family='${payload.font}']`)
    if (curFontDom) {
      fontSelectDom.innerText = curFontDom.innerText
      fontSelectDom.style.fontFamily = payload.font
      curFontDom.classList.add('active')
    }
    sizeOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
    const curSizeDom = sizeOptionDom.querySelector<HTMLLIElement>(`[data-size='${payload.size}']`)
    if (curSizeDom) {
      sizeSelectDom.innerText = curSizeDom.innerText
      curSizeDom.classList.add('active')
    } else {
      sizeSelectDom.innerText = `${payload.size}`
    }
    payload.bold ? boldDom.classList.add('active') : boldDom.classList.remove('active')
    payload.italic ? italicDom.classList.add('active') : italicDom.classList.remove('active')
    payload.underline ? underlineDom.classList.add('active') : underlineDom.classList.remove('active')
    payload.strikeout ? strikeoutDom.classList.add('active') : strikeoutDom.classList.remove('active')
    if (payload.color) {
      colorDom.classList.add('active')
      colorControlDom.value = payload.color
      colorSpanDom.style.backgroundColor = payload.color
    } else {
      colorDom.classList.remove('active')
      colorControlDom.value = '#000000'
      colorSpanDom.style.backgroundColor = '#000000'
    }
    if (payload.highlight) {
      highlightDom.classList.add('active')
      highlightControlDom.value = payload.highlight
      highlightSpanDom.style.backgroundColor = payload.highlight
    } else {
      highlightDom.classList.remove('active')
      highlightControlDom.value = '#ffff00'
      highlightSpanDom.style.backgroundColor = '#ffff00'
    }

    // 行布局
    leftDom.classList.remove('active')
    centerDom.classList.remove('active')
    rightDom.classList.remove('active')
    alignmentDom.classList.remove('active')
    justifyDom.classList.remove('active')
    if (payload.rowFlex && payload.rowFlex === 'right') {
      rightDom.classList.add('active')
    } else if (payload.rowFlex && payload.rowFlex === 'center') {
      centerDom.classList.add('active')
    } else if (payload.rowFlex && payload.rowFlex === 'alignment') {
      alignmentDom.classList.add('active')
    } else if (payload.rowFlex && payload.rowFlex === 'justify') {
      justifyDom.classList.add('active')
    } else {
      leftDom.classList.add('active')
    }

    // 行间距
    if (rowOptionDom) {
      rowOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
      const curRowMarginDom = rowOptionDom.querySelector<HTMLLIElement>(`[data-rowmargin='${payload.rowMargin}']`)
      if (curRowMarginDom) {
        curRowMarginDom.classList.add('active')
      }
    }

    // 功能
    payload.undo ? undoDom.classList.remove('no-allow') : undoDom.classList.add('no-allow')
    payload.redo ? redoDom.classList.remove('no-allow') : redoDom.classList.add('no-allow')
    payload.painter ? painterDom.classList.add('active') : painterDom.classList.remove('active')

    // 标题
    titleOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
    if (payload.level) {
      const curTitleDom = titleOptionDom.querySelector<HTMLLIElement>(`[data-level='${payload.level}']`)!
      titleSelectDom.innerText = curTitleDom.innerText
      curTitleDom.classList.add('active')
    } else {
      titleSelectDom.innerText = '正文'
      titleOptionDom.querySelector('li:first-child')!.classList.add('active')
    }

    // 列表
    listOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
    if (payload.listType) {
      listDom.classList.add('active')
      const listType = payload.listType
      const listStyle = payload.listType === ListType.OL ? ListStyle.DECIMAL : payload.listType
      const curListDom = listOptionDom.querySelector<HTMLLIElement>(`[data-list-type='${listType}'][data-list-style='${listStyle}']`)
      if (curListDom) {
        curListDom.classList.add('active')
      }
    } else {
      listDom.classList.remove('active')
    }

    // 批注
    commentDom.querySelectorAll<HTMLDivElement>('.comment-item').forEach(commentItemDom => {
      commentItemDom.classList.remove('active')
    })
    if (payload.groupIds) {
      const [id] = payload.groupIds
      const activeCommentDom = commentDom.querySelector<HTMLDivElement>(`.comment-item[data-id='${id}']`)
      if (activeCommentDom) {
        activeCommentDom.classList.add('active')
        scrollIntoView(commentDom, activeCommentDom)
      }
    }

    // 行列信息
    const rangeContext = instance.command.getRangeContext()
    if (rangeContext) {
      document.querySelector<HTMLSpanElement>('.row-no')!.innerText = `${rangeContext.startRowNo + 1}`
      document.querySelector<HTMLSpanElement>('.col-no')!.innerText = `${rangeContext.startColNo + 1}`
    }
  }

  // 可见页码列表变化
  instance.listener.visiblePageNoListChange = function (payload: number[]) {
    const text = payload.map(i => i + 1).join('、')
    document.querySelector<HTMLSpanElement>('.page-no-list')!.innerText = text
  }

  // 页面大小变化
  instance.listener.pageSizeChange = function (payload: string) {
    document.querySelector<HTMLSpanElement>('.page-size')!.innerText = `${payload}`
  }

  // 交叉页码变化
  instance.listener.intersectionPageNoChange = function (payload: number) {
    document.querySelector<HTMLSpanElement>('.page-no')!.innerText = `${payload + 1}`
  }

  // 页面缩放变化
  instance.listener.pageScaleChange = function (payload: number) {
    document.querySelector<HTMLSpanElement>('.page-scale-percentage')!.innerText = `${Math.floor(payload * 10 * 10)}%`
  }

  // 控件状态变化
  instance.listener.controlChange = function (payload: { state: ControlState }) {
    const disableMenusInControlContext = ['table', 'hyperlink', 'separator', 'page-break', 'control']
    // 菜单操作权限
    disableMenusInControlContext.forEach(menu => {
      const menuDom = document.querySelector<HTMLDivElement>(`.menu-item__${menu}`)!
      payload.state === ControlState.ACTIVE ? menuDom.classList.add('disable') : menuDom.classList.remove('disable')
    })
  }

  // 页面模式变化
  instance.listener.pageModeChange = function (payload: string) {
    const activeMode = pageModeOptionsDom.querySelector<HTMLLIElement>(`[data-page-mode='${payload}']`)!
    pageModeOptionsDom.querySelectorAll('li').forEach(li => li.classList.remove('active'))
    activeMode.classList.add('active')
  }

  // 内容变化处理函数
  const handleContentChange = async function () {
    // 字数
    const wordCount = await instance.command.getWordCount()
    document.querySelector<HTMLSpanElement>('.word-count')!.innerText = `${wordCount || 0}`
    // 目录
    if (isCatalogShow) {
      nextTick(() => {
        updateCatalog(instance)
      })
    }
    // 批注
    nextTick(() => {

      updateComment(instance, commentDom)
    })
  }

  // 设置内容变化监听器
  instance.listener.contentChange = debounce(handleContentChange, 200)
  handleContentChange()

  // 保存事件
  instance.listener.saved = function (payload: any) {
    console.log('elementList: ', payload)
  }
}

/**
 * 更新目录
 * @param instance 编辑器实例
 */
async function updateCatalog(instance: any) {
  const catalog = await instance.command.getCatalog()
  const catalogMainDom = document.querySelector<HTMLDivElement>('.catalog__main')!
  catalogMainDom.innerHTML = ''
  if (catalog) {
    const appendCatalog = (parent: HTMLDivElement, catalogItems: any[]) => {
      for (let c = 0; c < catalogItems.length; c++) {
        const catalogItem = catalogItems[c]
        const catalogItemDom = document.createElement('div')
        catalogItemDom.classList.add('catalog-item')
        // 渲染
        const catalogItemContentDom = document.createElement('div')
        catalogItemContentDom.classList.add('catalog-item__content')
        const catalogItemContentSpanDom = document.createElement('span')
        catalogItemContentSpanDom.innerText = catalogItem.name
        catalogItemContentDom.append(catalogItemContentSpanDom)
        // 定位
        catalogItemContentDom.onclick = () => {
          instance.command.executeLocationCatalog(catalogItem.id)
        }
        catalogItemDom.append(catalogItemContentDom)
        if (catalogItem.subCatalog && catalogItem.subCatalog.length) {
          appendCatalog(catalogItemDom, catalogItem.subCatalog)
        }
        // 追加
        parent.append(catalogItemDom)
      }
    }
    appendCatalog(catalogMainDom, catalog)
  }
}

/**
 * 更新批注
 * @param instance 编辑器实例
 * @param commentDom 批注DOM元素
 */
async function updateComment(instance: any, commentDom: HTMLDivElement) {
  const groupIds = await instance.command.getGroupIds()

  // 从window对象获取commentList
  const commentList = (window as any).commentList || []

  for (const comment of commentList) {
    const activeCommentDom = commentDom.querySelector<HTMLDivElement>(`.comment-item[data-id='${comment.id}']`)
    if (groupIds.includes(comment.id)) {
      // 当前dom是否存在-不存在则追加
      if (!activeCommentDom) {
        const commentItem = document.createElement('div')
        commentItem.classList.add('comment-item')
        commentItem.setAttribute('data-id', comment.id)
        commentItem.onclick = () => {
          instance.command.executeLocationGroup(comment.id)
        }
        // 选区信息
        const commentItemTitle = document.createElement('div')
        commentItemTitle.classList.add('comment-item__title')
        commentItemTitle.append(document.createElement('span'))
        const commentItemTitleContent = document.createElement('span')
        commentItemTitleContent.innerText = comment.rangeText
        commentItemTitle.append(commentItemTitleContent)
        const closeDom = document.createElement('i')
        closeDom.onclick = () => {
          instance.command.executeDeleteGroup(comment.id)
        }
        commentItemTitle.append(closeDom)
        commentItem.append(commentItemTitle)
        // 基础信息
        const commentItemInfo = document.createElement('div')
        commentItemInfo.classList.add('comment-item__info')
        const commentItemInfoName = document.createElement('span')
        commentItemInfoName.innerText = comment.userName
        const commentItemInfoDate = document.createElement('span')
        commentItemInfoDate.innerText = comment.createdDate
        commentItemInfo.append(commentItemInfoName)
        commentItemInfo.append(commentItemInfoDate)
        commentItem.append(commentItemInfo)
        // 详细评论
        const commentItemContent = document.createElement('div')
        commentItemContent.classList.add('comment-item__content')
        commentItemContent.innerText = comment.content
        commentItem.append(commentItemContent)
        commentDom.append(commentItem)
      }
    } else {
      // 编辑器内不存在对应成组id则dom则移除
      activeCommentDom?.remove()
    }
  }
}
